﻿//众所周知，高考数学中有一个题目是给出12个单项选择，每一个选择的答案是 A，B，C，D 中的一个。
//
//网上盛传答案存在某种规律，使得蒙对的可能性大大增加。于是今年老师想让你安排这12个题的答案。
//但是他有一些条件，首先四个选项的数量必须分别为 na，nb，nc，nd。
//其次有 m 个额外条件，分别给出两个数字 x，y，代表第 x 个题和第 y 个题的答案相同。
//现在你的老师想知道，有多少种可行的方案安排答案。
//
//输入描述 :
//	第一行五个非负整数na，nb，nc，nd，m，保证na + nb + nc + nd = 12，0≤m≤1000。
//	接下来m行每行两个整数x，y（1≤ x, y ≤12）代表第x个题和第y个题答案必须一样。
//
//输出描述 :
//	仅一行一个整数，代表可行的方案数。
//
//输入
//	3 3 3 3 0
//输出
//	369600

#include <iostream>
#include <vector>
using namespace std;
int cnt[5]; // ⽤数组存每⼀个选项出现多少次
int m, x, y;
bool same[13][13]; // 存哪些题的答案是相同的
int ret;
vector<int> path; // 记录路径⾥⾯选了哪些选项
bool isSame(int pos, int cur)
{
	for (int i = 1; i < pos; i++)
	{
		if (same[pos][i] && path[i] != cur) return false;
	}
	return true;
}
void dfs(int pos)
{
	if (pos > 12)
	{
		ret++;
		return;
	}

	for (int i = 1; i <= 4; i++)
	{
		if (cnt[i] == 0) continue; // 没有使⽤次数
		if (!isSame(pos, i)) continue; // 需要相同的位置，没有相同

		cnt[i]--;
		path.push_back(i);
		dfs(pos + 1);
		path.pop_back();
		cnt[i]++;
	}
}
int main()
{
	for (int i = 1; i <= 4; i++) cin >> cnt[i];
	cin >> m;
	while (m--)
	{
		cin >> x >> y;
		same[x][y] = same[y][x] = true;
	}

	path.push_back(0); // 先放进去⼀个占位符
	dfs(1);
	cout << ret << endl;

	return 0;
}